import 'package:flutter/material.dart';

class MacdPage extends StatelessWidget {
  const MacdPage({super.key});

  @override
  Widget build(BuildContext context) {
    return MaterialApp(
      home: Scaffold(
        appBar: AppBar(title: Text('MACD Chart')),
        body: Center(
          child: MACDChart(),
        ),
      ),
    );
  }
}

class MACDChart extends StatelessWidget {
  // 模拟的DIF数据
  final List<double> difData = [
    1.0,
    1.5,
    1.2,
    0.8,
    1.0,
    1.3,
    1.6,
    1.4,
    1.1,
    0.9
  ];
  // 模拟的DEA数据
  final List<double> deaData = [
    0.8,
    1.0,
    1.1,
    1.0,
    1.2,
    1.3,
    1.4,
    1.3,
    1.2,
    1.0
  ];
  // 模拟的MACD柱状图数据
  final List<double> macdData = [
    0.2,
    0.5,
    0.1,
    -0.2,
    -0.1,
    1.0,
    0.2,
    0.1,
    -1.1,
    -0.1
  ];

  @override
  Widget build(BuildContext context) {
    return CustomPaint(
      size: Size(300, 200),
      painter: MACDChartPainter(difData, deaData, macdData),
    );
  }
}

class MACDChartPainter extends CustomPainter {
  final List<double> difData;
  final List<double> deaData;
  final List<double> macdData;

  MACDChartPainter(this.difData, this.deaData, this.macdData);

  @override
  void paint(Canvas canvas, Size size) {
    final paint = Paint()
      ..color = Colors.blue
      ..strokeWidth = 2
      ..style = PaintingStyle.stroke;

    final deaPaint = Paint()
      ..color = Colors.red
      ..strokeWidth = 2
      ..style = PaintingStyle.stroke;

    final width = size.width / difData.length;
    final height = size.height / 2;

    // 绘制DIF线
    for (int i = 0; i < difData.length - 1; i++) {
      canvas.drawLine(
        Offset(i * width, height - difData[i] * 20), //20（简单的缩放因子）
        Offset((i + 1) * width, height - difData[i + 1] * 20), // 缩放 DIF 值
        paint,
      );
    }

    // 绘制DEA线
    for (int i = 0; i < deaData.length - 1; i++) {
      canvas.drawLine(
        Offset(i * width, height - deaData[i] * 20), // 缩放 DEA 值
        Offset((i + 1) * width, height - deaData[i + 1] * 20), // 缩放 DEA 值
        deaPaint,
      );
    }

    // 绘制MACD柱状图
    for (int i = 0; i < macdData.length; i++) {
      final macdPaint = Paint()
        ..color = macdData[i] >= 0 ? Colors.green : Colors.red
        ..strokeWidth = 1
        ..style = PaintingStyle.fill;

      canvas.drawRect(
        Rect.fromPoints(
          Offset(i * width, height),
          Offset((i + 1) * width, height - macdData[i] * 20), // 缩放 MACD 值
        ),
        macdPaint,
      );
    }
  }

  @override
  bool shouldRepaint(CustomPainter oldDelegate) {
    return true;
  }
}



/*

DIF、DEA 和 MACD 是技术分析中常用的指标，它们的计算基于指数移动平均线（EMA）。以下是它们的计算公式和步骤：

1. DIF（差离值）
DIF 是快速线，计算方法是 12日EMA 减去 26日EMA。

计算公式：
DIF
=
EMA
12
−
EMA
26
DIF=EMA 
12
​
 −EMA 
26
​
 
计算步骤：
计算 12 日 EMA：

首先计算 12 日简单移动平均线（SMA）。

然后使用 EMA 公式计算 12 日 EMA：

EMA
12
=
Price
t
×
2
12
+
1
+
EMA
12
,
t
−
1
×
(
1
−
2
12
+
1
)
EMA 
12
​
 =Price 
t
​
 × 
12+1
2
​
 +EMA 
12,t−1
​
 ×(1− 
12+1
2
​
 )
计算 26 日 EMA：

首先计算 26 日 SMA。

然后使用 EMA 公式计算 26 日 EMA：

EMA
26
=
Price
t
×
2
26
+
1
+
EMA
26
,
t
−
1
×
(
1
−
2
26
+
1
)
EMA 
26
​
 =Price 
t
​
 × 
26+1
2
​
 +EMA 
26,t−1
​
 ×(1− 
26+1
2
​
 )
计算 DIF：

DIF
=
EMA
12
−
EMA
26
DIF=EMA 
12
​
 −EMA 
26
​
 
2. DEA（信号线）
DEA 是慢速线，计算方法是 DIF 的 9 日 EMA。

计算公式：
DEA
=
EMA
9
(
DIF
)
DEA=EMA 
9
​
 (DIF)
计算步骤：
计算 DIF 的 9 日 EMA：

首先计算 DIF 的 9 日 SMA。

然后使用 EMA 公式计算 9 日 EMA：

DEA
=
DIF
t
×
2
9
+
1
+
DEA
t
−
1
×
(
1
−
2
9
+
1
)
DEA=DIF 
t
​
 × 
9+1
2
​
 +DEA 
t−1
​
 ×(1− 
9+1
2
​
 )
3. MACD（柱状图）
MACD 柱状图是 DIF 和 DEA 的差值。

计算公式：
MACD
=
DIF
−
DEA
MACD=DIF−DEA

4. 数据示例
假设我们有一组股票收盘价数据，以下是计算 DIF、DEA 和 MACD 的示例：

输入数据：
dart
复制
final List<double> prices = [10.0, 10.5, 11.0, 10.8, 11.5, 12.0, 11.8, 12.5, 13.0, 12.8];
计算步骤：
计算 12 日 EMA 和 26 日 EMA（假设数据足够）。

计算 DIF：
DIF=EMA12−EMA26
计算 DEA：
DEA=EMA 9(DIF)
计算 MACD：
MACD=DIF−DEA

5. 代码实现
以下是一个简单的 Dart 实现，用于计算 DIF、DEA 和 MACD：
class MACDCalculator {
  static List<double> calculateEMA(List<double> prices, int period) {
    List<double> ema = [];
    double multiplier = 2 / (period + 1);
    ema.add(prices.sublist(0, period).reduce((a, b) => a + b) / period); // SMA as initial EMA

    for (int i = period; i < prices.length; i++) {
      ema.add((prices[i] - ema[i - period]) * multiplier + ema[i - period]);
    }
    return ema;
  }

  static Map<String, List<double>> calculateMACD(List<double> prices) {
    List<double> ema12 = calculateEMA(prices, 12);
    List<double> ema26 = calculateEMA(prices, 26);

    List<double> dif = [];
    for (int i = 0; i < ema26.length; i++) {
      dif.add(ema12[i + 14] - ema26[i]); // Adjust indices for alignment
    }

    List<double> dea = calculateEMA(dif, 9);

    List<double> macd = [];
    for (int i = 0; i < dea.length; i++) {
      macd.add(dif[i + 8] - dea[i]); // Adjust indices for alignment
    }

    return {
      'dif': dif,
      'dea': dea,
      'macd': macd,
    };
  }
}

void main() {
  final List<double> prices = [10.0, 10.5, 11.0, 10.8, 11.5, 12.0, 11.8, 12.5, 13.0, 12.8];
  final macdData = MACDCalculator.calculateMACD(prices);

  print('DIF: ${macdData['dif']}');
  print('DEA: ${macdData['dea']}');
  print('MACD: ${macdData['macd']}');
}

6. 输出示例

假设输入价格为 [10.0, 10.5, 11.0, 10.8, 11.5, 12.0, 11.8, 12.5, 13.0, 12.8]，输出可能为:
DIF: [0.1, 0.2, 0.15, 0.3, 0.25]
DEA: [0.08, 0.12, 0.14, 0.18, 0.22]
MACD: [0.02, 0.08, 0.01, 0.12, 0.03]

7. 注意事项
数据对齐：由于 EMA 计算需要一定数量的初始数据，DIF、DEA 和 MACD 的长度会比原始价格数据短。

初始值：EMA 的初始值通常使用 SMA（简单移动平均）作为起点。

数据量：为了计算 26 日 EMA，至少需要 26 个价格数据点。


*/